﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.IO;
using TestMonkey.Models;
using System.Reflection;
using System.Xml.Linq;

namespace TestMonkey
{
    public class Setup
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Web.HtmlString")]
        public Setup()
        {
            TemplateLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        }


		public Setup(string projectFile, string projectDll, string testProjectFile)
			: this()
		{
			var project = XElement.Load(projectFile);

			var xmlns = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
			var rootNamespace = project.Descendants(xmlns + "RootNamespace").FirstOrDefault();
			if (rootNamespace != null)
				NamespaceRoot = rootNamespace.Value;

			var targetVersion = project.Descendants(xmlns + "TargetFrameworkVersion").FirstOrDefault();
			if (targetVersion != null && targetVersion.Value == "v4.0")
				SearchPaths.Add(@"C:\Windows\Microsoft.NET\Framework64\v4.0.30319");

			SourceDll = projectDll;

			var testProject = XElement.Load(testProjectFile);
			var testNamespace = testProject.Descendants(xmlns + "RootNamespace").FirstOrDefault();
			if (testNamespace != null)
				TestNamespace = testNamespace.Value;
			TargetFolder = Path.GetDirectoryName(testProjectFile);


		}

        public ObservableCollection<string> CustomTags
        {
            get { return m_CustomTags; }
        }

        public TestRunners.TestRunner TestRunner { get; set; }

        Func<Type, string, FileInfo> m_TargetFile;
        readonly ObservableCollection<string> m_SearchPaths = new ObservableCollection<string>();
        readonly ObservableCollection<string> m_CustomTags = new ObservableCollection<string>();

        public string SourceDll { get; set; }


        public ObservableCollection<string> SearchPaths
        {
            get { return m_SearchPaths; }
        }

        public bool ExcludeObsoleteProperties { get; set; }

        public string TemplateLocation { get; set; }

        public string TestNamespace { get; set; }

        public string TargetFolder { get; set; }

        public string NamespaceRoot { get; set; }

        public Func<Type, string, FileInfo> TargetFile
        {
            get { return m_TargetFile; }
            set
            {
                if (value == null)
                    throw new ArgumentNullException("value", "value is null.");
                m_TargetFile = value;
            }
        }


        public string GetPartialNamespace(Type type)
        {
            if (type == null)
                throw new ArgumentNullException("type", "type is null.");

            var partialNamespace = type.Namespace ?? "";
            if (partialNamespace.StartsWith(NamespaceRoot))
                partialNamespace = partialNamespace.Substring(NamespaceRoot.Length);
            if (partialNamespace.StartsWith("."))
                partialNamespace = partialNamespace.Substring(1);

            return partialNamespace;
        }

        public FileInfo GetTargetFile(ModelRoot model, Type type, string part)
        {
            if (model == null)
                throw new ArgumentNullException("model", "model is null.");
            if (type == null)
                throw new ArgumentNullException("type", "type is null.");
            if (String.IsNullOrEmpty(part))
                throw new ArgumentException("part is null or empty.", "part");

            string temp = model.Test.ClassName;
            foreach (var c in Path.GetInvalidFileNameChars())
            {
                temp = temp.Replace(c, '_');
            }

            string partialNamespace = GetPartialNamespace(type);

            partialNamespace = partialNamespace.Replace('.', Path.DirectorySeparatorChar);
            if (partialNamespace.StartsWith(Path.DirectorySeparatorChar.ToString()) || partialNamespace.StartsWith(Path.AltDirectorySeparatorChar.ToString()))

                partialNamespace = partialNamespace.Substring(1);

            return new FileInfo(Path.Combine(TargetFolder, partialNamespace, temp + "_" + part + ".cs"));
        }


        public bool UseTags { get; set; }
        public bool SkipTemplateOnError { get; set; }

    }


}


